#include <iostream>
#include <vector>
#include <string>
#include <set>
#include <algorithm>
using namespace std;

class Folder;
class Message
{
    friend class Folder;
    friend ostream &operator<<(ostream &, const Message &);
    friend void swap(Message &, Message &);

public:
    explicit Message(const string &s = string()) : contents(s), Folders(set<Folder *>()) {}
    Message(const Message &);
    Message &operator=(const Message &);
    ~Message();
    // 这两个才是一般情况下使用的成员函数 保存/移除
    void save(Folder &);
    void remove(Folder &);

private:
    string contents;
    set<Folder *> Folders;
    // 拷贝成员，析构函数需要用的工具函数
    void add_to_Folders(const Message &);
    void remove_from_Folders(); // 双向删除
    // used by Folder class to add self to this Message's set of Folder's
    void addFloder(Folder *f) { Folders.insert(f); }
    void removeFolder(Folder *f) { Folders.erase(f); }
};

class Folder
{
    friend void swap(Message &, Message &);
    friend Message;

public:
    Folder() = default;
    Folder(const Folder &);
    ~Folder();
    Folder &operator=(const Folder &);
    void save(Message &m)
    {
        Msgs.insert(&m);
        m.addFloder(this);
    }
    void remove(Message &m)
    {
        Msgs.erase(&m);
        m.removeFolder(this);
    }

private:
    set<Message *> Msgs;
    // 拷贝成员，以及析构函数所需要的工具函数
    void add_to_Messages(const Folder &);
    void remove_from_Msgs(); // 双向删除，不同于Message的
    //
    void addMsg(Message *pm) { Msgs.insert(pm); }
    void removeMsg(Message *pm) { Msgs.erase(pm); }
};

void Folder::add_to_Messages(const Folder &f)
{
    for (auto &i : f.Msgs)
        i->addFloder(this);
}

void Folder::remove_from_Msgs()
{
    while (!Msgs.empty())
        (*Msgs.begin())->remove(*this);
}

Folder::Folder(const Folder &f) : Msgs(f.Msgs)
{
    add_to_Messages(f);
}

Folder::~Folder()
{
    remove_from_Msgs();
}

Folder &Folder::operator=(const Folder &f)
{
    remove_from_Msgs();
    Msgs = f.Msgs;
    add_to_Messages(f);
    return *this;
}

//``````````````````````````````````````````````````````````
void Message::save(Folder &f)
{
    Folders.insert(&f);
    f.addMsg(this);
}

void Message::remove(Folder &f)
{
    Folders.erase(&f);
    f.removeMsg(this);
}

void Message::add_to_Folders(const Message &m)
{
    for (auto &i : m.Folders)
        i->addMsg(this); // i是Folder*
}

void Message::remove_from_Folders()
{
    for (auto &i : Folders)
        i->removeMsg(this);
    Folders.clear();
}

Message::Message(const Message &m) : Folders(m.Folders), contents(m.contents)
{
    add_to_Folders(m);
}

Message::~Message()
{
    remove_from_Folders();
}

Message &Message::operator=(const Message &m)
{
    remove_from_Folders();
    Folders = m.Folders;
    contents = m.contents;
    add_to_Folders(m);
    return *this;
}

ostream &operator<<(ostream &os, const Message &m)
{
    os << m.contents;
    return os;
}

void swap(Message &lhs, Message &rhs)
{
    using std::swap;
    cout << "???????????" << endl;
    for (auto &i : lhs.Folders)
        i->removeMsg(&lhs);
    for (auto &i : rhs.Folders)
        i->removeMsg(&rhs);
    swap(lhs.contents, rhs.contents);
    swap(lhs.Folders, rhs.Folders);
    for (auto &i : lhs.Folders)
        i->addMsg(&lhs);
    for (auto &i : rhs.Folders)
        i->addMsg(&rhs);
}

int main()
{
    Message m1("111");
    Message m2("222");
    Message m3("333");
    Message m4("444");
    Folder f1;
    Folder f2;
    m1.save(f1);
    m2.save(f1);
    m3.save(f2);
    m4.save(f2);

    m1 = m3;
    cout << &m2 << endl;
    cout << &m4 << endl;
    swap(m2, m4);
    cout << &m2 << endl;
    cout << &m4 << endl;
    return 0;
}